<template>
  <div class="modal-overlay">
  <div class="similarity-search-dialog modal-main" :style="{ left: position.x + 'px', top: position.y + 'px' }">
    <div class="dialog-header modal-header" @mousedown="startDrag" :style="{ cursor: isDragging ? 'grabbing' : 'grab' }">
      <h2>曲线相似性检索</h2>
      <button class="close-btn" @click="$emit('close')">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <line x1="18" y1="6" x2="6" y2="18"></line>
          <line x1="6" y1="6" x2="18" y2="18"></line>
        </svg>
      </button>
    </div>
    
    <div class="dialog-content">
      <!-- 上方：已保存的曲线样本 -->
      <div class="top-panel">
        <div class="panel-header">
          <h3 class="panel-title">已保存的曲线样本</h3>
          <div class="header-actions">
            <button class="action-btn config-btn tech-btn" @click="showConfig">
              检索配置
            </button>
            <button class="action-btn tech-btn" @click="addSample">
              新增样本
            </button>
            <button class="action-btn tech-btn" @click="searchWithSamples" :disabled="selectedSamples.length === 0">
              使用样本检索
            </button>
          </div>
        </div>
        
        <div class="sample-table-container">
          <div class="table-header">
            <div class="tech-checkbox">
              <input
                type="checkbox"
                :checked="isAllSamplesSelected"
                @change="toggleAllSamples"
                class="select-all-checkbox"
              />
<!--              <span class="checkbox-custom"></span>-->
            </div>
            <span>样本名称</span>
            <span>参数名称</span>
            <span>样本范围</span>
            <span>最低相似度</span>
            <span>操作</span>
          </div>
          
          <div class="table-body">
            <div
              v-for="(sample, index) in savedSamples"
              :key="sample.id"
              class="table-row"
            >
              <div class="tech-checkbox">
                <input
                  type="checkbox"
                  :id="`sample-${sample.id}`"
                  v-model="selectedSamples"
                  :value="sample.id"
                  class="sample-checkbox"
                />
<!--                <span class="checkbox-custom"></span>-->
              </div>
              <span class="sample-name">{{ sample.sampleName }}</span>
              <span class="param-name">{{ sample.paramName }}</span>
              <span class="sample-range">{{ sample.startTime }} - {{ sample.endTime }}</span>
              <span class="similarity-threshold">{{ sample.similarity }}%</span>
              <div class="row-actions">
<!--                <button class="action-btn play-btn" @click="playSample(sample)">-->
<!--                  回放-->
<!--                </button>-->
                <button class="action-btn edit-btn tech-btn" @click="editSample(sample)">
                  编辑
                </button>
                <button class="action-btn delete-btn tech-btn-warn" @click="deleteSample(sample)">
                  删除
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 下方：曲线相似性检索的结果 -->
      <div class="bottom-panel">
        <div class="panel-header">
          <h3 class="panel-title">曲线相似性检索的结果</h3>
          <div class="header-actions">
            <button class="action-btn tech-btn" @click="batchAnnotate" :disabled="selectedResults.length === 0">
              批量标注
            </button>
            <button class="action-btn tech-btn-warn" @click="batchClearAnnotate" :disabled="selectedResults.length === 0">
              批量取消标注
            </button>
          </div>
        </div>
        
        <div class="result-table-container">
          <div class="table-header">
            <div class="tech-checkbox">
              <input
                type="checkbox"
                :checked="isAllResultsSelected"
                @change="toggleAllResults"
                class="select-all-checkbox"
              />
<!--              <span class="checkbox-custom"></span>-->
            </div>
            <span>样本名</span>
            <span>参数名</span>
            <span>文件名</span>
            <span>起始时间</span>
            <span>结束时间</span>
            <span>相似度</span>
            <span>操作</span>
          </div>
          
          <div class="table-body">
            <div
              v-for="(result, index) in searchResults"
              :key="result.id"
              class="table-row"
            >
              <div class="tech-checkbox">
                <input
                  type="checkbox"
                  :id="`result-${result.id}`"
                  v-model="selectedResults"
                  :value="result.id"
                  class="result-checkbox"
                />
<!--                <span class="checkbox-custom"></span>-->
              </div>
              <span class="sample-name">{{ result.sampleName }}</span>
              <span class="param-name">{{ result.paramName }}</span>
              <span class="file-name">{{ result.fileName }}</span>
              <span class="start-time">{{ result.similarityDataStartTime }}</span>
              <span class="end-time">{{ result.similarityDataEndTime }}</span>
              <span class="similarity-score">{{ result.similarity }}%</span>
              <div class="row-actions">
                <button 
                  v-if="!result.isAnnotated" 
                  class="action-btn annotate-btn tech-btn"
                  @click="annotateResult(result)"
                >
                  标注
                </button>
                <button 
                  v-else 
                  class="action-btn tech-btn-warn"
                  @click="clearAnnotate(result)"
                >
                  取消标注
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <!-- Loading遮罩层 -->
    <div v-if="isLoading" class="loading-overlay">
      <div class="spinner"></div>
    </div>
  </div>
  
  <!-- 消息提示组件 -->
  <Message ref="messageRef" />
  
  <!-- 检索配置弹窗 -->
  <div v-if="showConfigDialog" class="config-overlay">
    <div class="config-dialog modal-main" @click.stop>
      <div class="config-header modal-header">
        <h3>检索配置</h3>
        <button class="close-btn" @click="showConfigDialog = false">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <line x1="18" y1="6" x2="6" y2="18"></line>
            <line x1="6" y1="6" x2="18" y2="18"></line>
          </svg>
        </button>
      </div>
      <div class="config-content">
        <div class="config-item">
          <label>检索窗口步长:</label>
          <input type="number" v-model="config.searchWindowStep"/>
        </div>
        <div class="config-item">
          <label>下采样率:</label>
          <input type="number" v-model="config.downSamplingRate" />
        </div>
        <div class="config-item">
          <label>单文件最大检索数量:</label>
          <input type="number" v-model="config.singleFileSearchMax" />
        </div>
        <div class="config-item">
          <label>仅进行形状检索:</label>
          <input type="checkbox" v-model="config.isNeedShapeSearch"/>
        </div>
      </div>
      <div class="config-actions">
        <button class="action-btn tech-btn-warn" @click="resetConfig">重置默认</button>
        <button class="action-btn tech-btn" @click="saveConfig">保存配置</button>
      </div>
    </div>
  </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue'
import Message from '@/components/BaseComponents/Message.vue'
import API from './similaritySearch.api'
import { useSimilarityStore } from '@/stores/similarity'


// 消息提示组件引用
const messageRef = ref<InstanceType<typeof Message> | null>(null)

const similarityStore = useSimilarityStore()

interface Sample {
  paramName: string
  id: string
  sampleName: string
  startTime: string
  endTime: string
  similarity: number
  fileName: string
  signalId?: number
  data?: any
}

interface SearchResult {
  id: string
  sampleName: string
  paramName: string
  fileName: string
  similarityDataStartTime: string
  similarityDataEndTime: string
  similarity: number
  isAnnotated?: boolean
  data?: any
}

const props = defineProps<{
  selectedChannel: any[]
  selectedParametersInfo: any[]
}>()

const emit = defineEmits<{
  (e: 'close'): void
  (e: 'playSample', sample: Sample): void
  (e: 'editSample', sample: Sample): void
  (e: 'deleteSample', sample: Sample): void
  (e: 'annotateResult', result: SearchResult): void
  (e: 'clearAnnotateResult', result: SearchResult): void
  (e: 'batchAnnotate', results: SearchResult[]): void
  (e: 'batchClearAnnotate', results: SearchResult[]): void
  (e: 'openAddSample'): void
  (e: 'clearAllAnnotate'): void
}>()

// 拖动相关状态


const position = ref({ x: 100, y: 100 })
const isDragging = ref(false)
const dragStart = ref({ x: 0, y: 0 })
const initialPosition = ref({ x: 0, y: 0 })

// 获取当前窗口实际尺寸
const getDialogSize = () => {
  const screenWidth = window.innerWidth
  const screenHeight = window.innerHeight
  
  if (screenWidth <= 1024) {
    return {
      width: Math.min(screenWidth * 0.4, 600),
      height: Math.min(screenHeight * 0.85, 700)
    }
  } else {
    return {
      width: screenWidth * 0.5,
      height: screenHeight * 0.8
    }
  }
}

// 拖动功能
const startDrag = (event: MouseEvent) => {
  if (event.target === event.currentTarget || (event.target as Element).tagName === 'H2') {
    isDragging.value = true
    dragStart.value = { x: event.clientX, y: event.clientY }
    initialPosition.value = { x: position.value.x, y: position.value.y }
    document.addEventListener('mousemove', handleDrag)
    document.addEventListener('mouseup', stopDrag)
    event.preventDefault()
  }
}

const handleDrag = (event: MouseEvent) => {
  if (!isDragging.value) return
  
  const deltaX = event.clientX - dragStart.value.x
  const deltaY = event.clientY - dragStart.value.y
  
  const dialogSize = getDialogSize()
  
  position.value = {
    x: Math.max(0, Math.min(window.innerWidth - dialogSize.width, initialPosition.value.x + deltaX)),
    y: Math.max(0, Math.min(window.innerHeight - dialogSize.height, initialPosition.value.y + deltaY))
  }
}

const stopDrag = () => {
  isDragging.value = false
  document.removeEventListener('mousemove', handleDrag)
  document.removeEventListener('mouseup', stopDrag)
}

// 窗口大小变化时调整位置
const handleResize = () => {
  const dialogSize = getDialogSize()
  position.value = {
    x: Math.max(0, Math.min(window.innerWidth - dialogSize.width, position.value.x)),
    y: Math.max(0, Math.min(window.innerHeight - dialogSize.height, position.value.y))
  }
}

// 组件挂载时设置初始位置为居中
onMounted(async () => {
  await nextTick()
  
  const dialogSize = getDialogSize()
  const centerX = Math.max(0, (window.innerWidth - dialogSize.width) / 2)
  const centerY = Math.max(0, (window.innerHeight - dialogSize.height) / 2)
  
  position.value = {
    x: centerX,
    y: centerY
  }
  
  window.addEventListener('resize', handleResize)
  
  // 从 localStorage 恢复上次的检索结果
  loadLastSearchResults()
  loadSavedSamples()
})

// 组件卸载时清理事件监听器
onUnmounted(() => {
  document.removeEventListener('mousemove', handleDrag)
  document.removeEventListener('mouseup', stopDrag)
  window.removeEventListener('resize', handleResize)
  
  // 弹窗关闭时保存检索结果
  saveCurrentSearchResults()
})

// 状态管理
const isLoading = ref(false)
const savedSamples = ref<Sample[]>([])
const searchResults = ref<SearchResult[]>([])
const selectedSamples = ref<string[]>([])
const selectedResults = ref<string[]>([])

// 配置弹窗状态
const showConfigDialog = ref(false)
const config = ref({
  searchWindowStep: 10,
  downSamplingRate: 50,
  singleFileSearchMax: 10,
  isNeedShapeSearch: true
})

// 配置相关方法
const resetConfig = () => {
  config.value = {
    searchWindowStep: 10,
    downSamplingRate: 50,
    singleFileSearchMax: 10,
    isNeedShapeSearch: true
  }
}

const saveConfig = async () => {
  // 调接口
  try {
    const res: any = await API.updateSearchConfig(config.value)
    if (res.code === 200) {
      messageRef.value?.show({
        type: 'success',
        content: '配置已保存',
        duration: 2000
      })
      // 关闭配置弹窗
      showConfigDialog.value = false
    }
  } catch (error: any) {
    messageRef.value?.show({
      type: 'warning',
      content: error.response.data.msg,
      duration: 3000
    })
  }
}

// 计算属性
const isAllSamplesSelected = computed(() => {
  return savedSamples.value.length > 0 && selectedSamples.value.length === savedSamples.value.length
})

const isAllResultsSelected = computed(() => {
  return searchResults.value.length > 0 && selectedResults.value.length === searchResults.value.length
})

// 打开配置
const showConfig = async () => {
  showConfigDialog.value = true
  try {
    const res: any = await API.getSearchConfig()
    if (res.code === 200) {
      config.value = res.data
    }
  } catch (error: any) {
    messageRef.value?.show({
      type: 'warning',
      content: error.response.data.msg,
      duration: 3000
    })
  }
}

// 全选/取消全选样本
const toggleAllSamples = () => {
  if (isAllSamplesSelected.value) {
    selectedSamples.value = []
  } else {
    selectedSamples.value = savedSamples.value.map(sample => sample.id)
  }
}

// 全选/取消全选结果
const toggleAllResults = () => {
  if (isAllResultsSelected.value) {
    selectedResults.value = []
  } else {
    selectedResults.value = searchResults.value.map(result => result.id)
  }
}

// 新增样本
const addSample = () => {
  emit('openAddSample')
}

// 使用样本检索
const searchWithSamples = async () => {
  if (selectedSamples.value.length === 0) {
    messageRef.value?.show({
      type: 'warning',
      content: '请先选择要检索的样本',
      duration: 3000
    })
    return
  }
  
  isLoading.value = true
  try {
    const selectedSampleResults = savedSamples.value.filter(sample => selectedSamples.value.includes(sample.id))
    
    // 清除之前的结果
    searchResults.value = []
    selectedResults.value = []

    const sampleIds = selectedSampleResults.map(sample => sample.id)
    const fileNames = props.selectedChannel.map(channel => channel.fileName)
    // fileNames 中只保留有值的
    const validFileNames = fileNames.filter(fileName => fileName)
    let params = { idList: sampleIds, fileName: validFileNames }
    const res: any = await API.searchSimilarity(params)
    if (res.code === 200) {
      // 初始化标注状态为false
      const resultsWithAnnotationStatus = (res.data || []).map((result: SearchResult) => ({
        ...result,
        isAnnotated: false
      }))
      searchResults.value = resultsWithAnnotationStatus
      // 保存检索结果到store
      saveCurrentSearchResults()
      // 取消当前图上所有标注
      emit('clearAllAnnotate')

      messageRef.value?.show({
        type: 'success',
        content: '检索完成',
        duration: 3000
      })
    }
  } catch (error: any) {
    messageRef.value?.show({
      type: 'warning',
      content: error.response.data.msg,
      duration: 3000
    })
  } finally {
    isLoading.value = false
  }
}

// 回放样本
const playSample = (sample: Sample) => {
  emit('playSample', sample)
}

// 编辑样本
const editSample = (sample: Sample) => {
  emit('editSample', sample)
}

// 删除样本
const deleteSample = async (sample: Sample) => {
  if (confirm(`确定要删除样本"${sample.sampleName}"吗？`)) {
    isLoading.value = true
    try {
      // 从后端删除样本
      const res: any = await API.deleteSample(sample.id)
      if (res.code === 200) {
        messageRef.value?.show({
          type: 'success',
          content: '删除样本成功',
          duration: 3000
        })
        // 更新样本列表
        loadSavedSamples()
        // 取消该样本的标注
        const annotatedResults = searchResults.value.filter(result => result.sampleName === sample.sampleName)
        selectedResults.value = selectedResults.value.filter(id => !annotatedResults.map(result => result.id).includes(id))
        emit('batchClearAnnotate', annotatedResults)

        // 如果已选中，则取消选中
        selectedSamples.value = selectedSamples.value.filter(id => id !== sample.id)
        //重新检索
        if (selectedSamples.value.length === 0) {
          searchResults.value = []
          selectedResults.value = []
          saveCurrentSearchResults()
          return
        }
        // 在结果列表删除该样本
        searchResults.value = searchResults.value.filter(result => result.sampleName !== sample.sampleName)
        saveCurrentSearchResults()
      }
    } catch (error: any) {
      messageRef.value?.show({
        type: 'warning',
        content: error.response.data.msg,
        duration: 3000
      })
    } finally {
      isLoading.value = false
    }
  }
}

// 标注结果
const annotateResult = (result: SearchResult) => {
  // 设置标注状态
  // 判断所选结果的对应参数是否在selectedParametersInfo中
  const selectedParameter = props.selectedParametersInfo.find(param => param.name === result.paramName)
  if (selectedParameter) {
    result.isAnnotated = true
    emit('annotateResult', result)
    saveCurrentSearchResults()
  } else {
    messageRef.value?.show({
      type: 'warning',
      content: '请先选择对应参数绘图',
      duration: 3000
    })
  }
}

// 取消标注结果
const clearAnnotate = (result: SearchResult) => {
  // 设置标注状态
  result.isAnnotated = false
  emit('clearAnnotateResult', result)
  saveCurrentSearchResults()
}

// 批量标注
const batchAnnotate = () => {
  if (selectedResults.value.length === 0) {
    messageRef.value?.show({
      type: 'warning',
      content: '请先选择要标注的结果',
      duration: 3000
    })
    return
  }
  
  const selectedResultData = searchResults.value.filter(result =>
    selectedResults.value.includes(result.id)
  )
  let isAllParametersSelected = true

  // 判断selectedResults中包含的所有参数是否都在selectedParametersInfo中
  selectedResultData.forEach((result) => {
    const selectedParameter = props.selectedParametersInfo.find(param => param.name === result.paramName)
    if (!selectedParameter) {
      messageRef.value?.show({
        type: 'warning',
        content: '请先选择对应参数绘图',
        duration: 3000
      })
      isAllParametersSelected = false
    }
  })

  if (!isAllParametersSelected) {
    return
  } else {
    // 批量设置标注状态
    selectedResultData.forEach(result => {
      result.isAnnotated = true
    })
    
    emit('batchAnnotate', selectedResultData)
    saveCurrentSearchResults()
  }
}

// 批量取消标注
const batchClearAnnotate = () => {
  if (selectedResults.value.length === 0) {
    messageRef.value?.show({
      type: 'warning',
      content: '请先选择要取消标注的结果',
      duration: 3000
    })
    return
  }
  
  const clearedResults = searchResults.value.filter(result => 
    selectedResults.value.includes(result.id)
  )
  
  // 批量设置标注状态
  clearedResults.forEach(result => {
    result.isAnnotated = false
  })
  
  emit('batchClearAnnotate', clearedResults)
  saveCurrentSearchResults()
}

// 加载已保存的样本
const loadSavedSamples = async () => {
  isLoading.value = true
  try {
    // 从后端获取已保存的样本
    const res: any = await API.getSavedSamples()
    if (res.code === 200) {
      savedSamples.value = res.data || []
    }
  } catch (error: any) {
    messageRef.value?.show({
      type: 'warning',
      content: error.response.data.msg,
      duration: 3000
    })
  } finally {
    isLoading.value = false
  }
}

// 保存当前检索结果到store
const saveCurrentSearchResults = () => {
  similarityStore.updateSelectedSample(selectedSamples.value)
  similarityStore.updateSearchResult(searchResults.value)
};

// 从 store恢复上次的检索结果
const loadLastSearchResults = () => {
  searchResults.value = similarityStore.searchResults
  selectedSamples.value = similarityStore.selectedSample
};

// 处理参数被移除的情况，清除对应参数的标注状态
const handleParametersRemoved = (removedParams: string[]) => {
  if (removedParams.length === 0) return;
  
  // 清除被移除参数的标注状态
  searchResults.value.forEach(result => {
    if (removedParams.includes(result.paramName)) {
      result.isAnnotated = false;
    }
  });
  
  // 保存更新后的状态
  saveCurrentSearchResults();
  
  console.log('清除被移除参数的标注状态:', removedParams);
};

// 暴露方法给父组件
defineExpose({
  handleParametersRemoved
})
</script>

<style scoped>
@import '../../../src/assets/css/theme.css';
@import '../../../src/assets/css/buttons.css';
@import '../../../src/assets/css/modal.css';
*{
  -webkit-touch-callout:none;
  -webkit-user-select:none;
  -khtml-user-select:none;
  -moz-user-select:none;
  -ms-user-select:none;
  user-select:none;
}
.modal-overlay{
    display:flex;
    justify-content: center;
    align-items: center;
}
.similarity-search-dialog {
  position: fixed;
  width: 50%;
  height: 80%;
  backdrop-filter: blur(10px);
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
  /*border: 1px solid red !important;*/
  z-index: 9999;
  animation: modalAppear 0.3s ease-out;
}
@keyframes modalAppear {
  from {
    opacity: 0;
    transform: scale(0.9);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.similarity-search-dialog::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  z-index: 10000;
}

.dialog-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  position: relative;
  z-index: 2;
  user-select: none;
  transition: background-color 0.2s ease;
}

.dialog-header h2 {
  margin: 0;
    color: var(--text-color);
  font-size: 18px;
  font-weight: 600;
}

.close-btn {
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
  color: var(--text-color);
  font-size: 20px;
  font-weight: 700;
  transition: color 0.2s;
}

.close-btn:hover {
    color: rgba(0, 0, 0, 0.85);
}

.dialog-content {
  display: flex;
  flex-direction: column;
  flex: 1;
  overflow: hidden;
}

.top-panel,
.bottom-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.top-panel {
  border-bottom: 1px solid rgba(30, 64, 175, 0.1);
}

.bottom-panel {
  border-top: 1px solid rgba(30, 64, 175, 0.1);
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid var(--modal-divide);
  border-top: 1px solid var(--modal-divide);
    background: var(--se-sub-plate-bg-color);
}

.panel-title {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

.header-actions {
  display: flex;
  gap: 6px;
}

.action-btn {
  padding: 4px 8px;
  max-height: 30px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.2s ease;
}

.action-btn:disabled {
  cursor: not-allowed;
}

.config-btn {
  background: rgba(30, 64, 175, 0.08);
  border-color: rgba(30, 64, 175, 0.25);
  color: #1e3a8a;
}

.config-btn:hover:not(:disabled) {
  background: rgba(30, 64, 175, 0.18);
  border-color: rgba(30, 64, 175, 0.45);
}

.sample-table-container,
.result-table-container {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* 已保存的曲线样本表格 - 列宽分配 */
.sample-table-container .table-header {
  display: grid;
  grid-template-columns: 30px 1fr 120px 150px 110px 160px;
  padding: 10px 16px;
  background: var(--table-body-bg-color);
  border-bottom: 1px solid var(--table-solid);
  font-weight: 600;
  color: var(--text-color);
  position: sticky;
  top: 0;
  z-index: 10;
  align-items: center;
  margin-right: 12px; /* 为滚动条预留空间 */
}

.sample-table-container .table-header span {
  text-align: center;
}

.sample-table-container .table-row {
  display: grid;
  grid-template-columns: 30px 1fr 120px 150px 110px 160px;
  padding: 8px 16px;
  border-bottom: 1px solid var(--table-solid);
  align-items: center;
  transition: background-color 0.2s;
  min-height: 40px;
    color:var(--text-color);
    background: var(--table-body-bg-color);
}

/* 曲线相似性检索结果表格 - 列宽分配 */
.result-table-container .table-header {
  display: grid;
  grid-template-columns: 30px 1fr 120px 130px 75px 75px 80px 100px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--table-solid);
  font-weight: 600;
  position: sticky;
  top: 0;
  z-index: 10;
  align-items: center;
  margin-right: 12px; /* 为滚动条预留空间 */
}

.result-table-container .table-header span {
  text-align: center;
}

.result-table-container .table-row {
  display: grid;
  grid-template-columns: 30px 1fr 120px 130px 75px 75px 80px 100px;
  padding: 8px 16px;
  border-bottom: 1px solid var(--table-solid);
  align-items: center;
  transition: background-color 0.2s;
  min-height: 40px;
    color:var(--text-color);
    background: var(--table-body-bg-color);
}

.table-body {
  flex: 1;
  overflow-y: auto;
  scrollbar-gutter: stable; /* 为现代浏览器提供稳定的滚动条空间 */
}

.select-all-checkbox,
.sample-checkbox,
.result-checkbox{
    border: 1px solid var(--btn-click-color);
    background-color: var(--ant-checkbox-inner);
    color: var(--global-color-white);
    appearance: none;
    -webkit-appearance: none;
    width: 16px ;
    height: 16px ;
    border-radius: 4px; /* 圆角 */
    outline: none;
    cursor: pointer;
    position: relative;
    transition: all 0.2s ease; /* 平滑过渡效果 */
}
.select-all-checkbox:checked,
.sample-checkbox:checked,
.result-checkbox:checked{
    color: var(--global-color-white);
    background-color: var(--ant-checkbox-checked);
    border-color: var(--btn-click-color);
}
.select-all-checkbox:checked::after,
.sample-checkbox:checked::after,
.result-checkbox:checked::after{
    content: "";
    position: absolute;
    left: 30%;
    top: 1px;
    width: 6px;
    height: 10px;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

/* 所有文字居中显示 */
.row-number,
.file-name,
.sample-name,
.param-name,
.start-time,
.end-time,
.sample-range,
.similarity-threshold,
.similarity-score {
  text-align: center;
  font-weight: 500;
  word-wrap: break-word;
  word-break: break-all;
  white-space: normal;
  line-height: 1.4;
  padding: 2px 2px;
  min-height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  max-height: none;
  font-size: 14px;
}

.row-actions {
  display: flex;
  gap: 4px;
  justify-content: center;
  align-items: center;
  height: 100%;
  flex-wrap: wrap;
}

.play-btn {
  background: rgba(34, 197, 94, 0.1);
  border-color: rgba(34, 197, 94, 0.3);
  color: #16a34a;
  padding: 3px 6px;
  font-size: 14px;
}

.play-btn:hover {
  background: rgba(34, 197, 94, 0.2);
  border-color: rgba(34, 197, 94, 0.5);
}

.edit-btn {
  background: rgba(245, 158, 11, 0.1);
  border-color: rgba(245, 158, 11, 0.3);
  color: #d97706;
  padding: 3px 6px;
  font-size: 14px;
}

.edit-btn:hover {
  background: rgba(245, 158, 11, 0.2);
  border-color: rgba(245, 158, 11, 0.5);
}

.delete-btn {
  background: rgba(239, 68, 68, 0.1);
  border-color: rgba(239, 68, 68, 0.3);
  color: #dc2626;
  padding: 3px 6px;
  font-size: 14px;
}

.delete-btn:hover {
  background: rgba(239, 68, 68, 0.2);
  border-color: rgba(239, 68, 68, 0.5);
}

.annotate-btn {
  background: rgba(168, 85, 247, 0.1);
  border-color: rgba(168, 85, 247, 0.3);
  color: #9333ea;
  padding: 3px 6px;
  font-size: 14px;
}

.annotate-btn:hover {
  background: rgba(168, 85, 247, 0.2);
  border-color: rgba(168, 85, 247, 0.5);
}

/* Loading样式 */
.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--loading-bg-color);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10000;
  border-radius: 12px;
}

.spinner {
  border: 5px solid #fcfcfc;
  border-top: 5px solid #3498db;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* 配置弹窗样式 */
.config-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10001;
}

.config-dialog {
  border-radius: 8px;
  padding: 0;
  min-width: 400px;
  max-width: 500px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
}

.config-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid #e5e7eb;
}

.config-header h3 {
  margin: 0;
  color: var(--text-color);
  font-size: 16px;
  font-weight: 600;
}

.config-content {
  padding: 20px;
}

.config-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.config-item label {
  font-weight: 500;
  color: var(--text-color);
  min-width: 120px;
}

.config-item input[type="number"] {
  width: 80px;
  padding: 6px 8px;
  border-radius: 4px;
  text-align: center;
  background: var(--select-background);
  color: var(--text-color);
  border: 1px solid var(--input-border-color);
}

.config-item input[type="checkbox"] {
  width: 18px;
  height: 18px;
  border: 1px solid var(--btn-click-color);
  background-color: var(--ant-checkbox-inner);
  color: var(--global-color-white);
  appearance: none;
  -webkit-appearance: none;
  border-radius: 4px; /* 圆角 */
  outline: none;
  cursor: pointer;
  position: relative;
  transition: all 0.2s ease; /* 平滑过渡效果 */
}

.config-item input[type="checkbox"]:checked{
    color: var(--global-color-white);
    background-color: var(--ant-checkbox-checked);
    border-color: var(--btn-click-color);
}

.config-item input[type="checkbox"]:checked::after{
    content: "";
    position: absolute;
    left: 30%;
    top: 1px;
    width: 6px;
    height: 10px;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}
.config-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding: 16px 20px;
  border-top: 1px solid #e5e7eb;
}

/* 响应式设计 */
@media (max-width: 1024px) {
  .similarity-search-dialog {
    width: 40vw;
    height: 85vh;
    max-width: 600px;
    max-height: 700px;
  }
  
  .dialog-header {
    padding: 10px 12px;
  }
  
  .dialog-header h2 {
    font-size: 15px;
  }
  
  .panel-header {
    padding: 10px 12px;
  }
  
  .panel-title {
    font-size: 12px;
  }
  
  .action-btn {
    font-size: 10px;
    padding: 3px 6px;
  }
  
  /* 已保存的曲线样本表格 - 响应式列宽 */
  .sample-table-container .table-header {
    grid-template-columns: 25px 1fr 80px 80px 60px 80px;
    padding: 8px 12px;
    font-size: 12px;
  }
  
  .sample-table-container .table-header span {
    text-align: center;
  }
  
  .sample-table-container .table-row {
    grid-template-columns: 25px 1fr 80px 80px 60px 80px;
    padding: 8px 12px;
    font-size: 12px;
    align-items: center;
    min-height: 35px;
      color:var(--text-color);
      background: var(--table-body-bg-color);
  }
  
  /* 曲线相似性检索结果表格 - 响应式列宽 */
  .result-table-container .table-header {
    grid-template-columns: 25px 80px 80px 60px 80px 80px 60px 70px;
    padding: 8px 12px;
    font-size: 12px;
  }
  
  .result-table-container .table-header span {
    text-align: center;
  }
  
  .result-table-container .table-row {
    grid-template-columns: 25px 80px 80px 60px 80px 80px 60px 70px;
    padding: 8px 12px;
    font-size: 12px;
    align-items: center;
    min-height: 35px;
      color:var(--text-color);
      background: var(--table-body-bg-color);
  }
  
  .row-actions {
    gap: 2px;
  }
  
  .play-btn,
  .edit-btn,
  .delete-btn,
  .annotate-btn {
    padding: 2px 4px;
    font-size: 12px;
  }
}
</style>